/**
 * @file util/createItem 适配iris sdk，构造一个老sdk产出的item
 * @author fanxueliang
 */
import type {UnionSpecItem, EnumValuesSpecItem} from '../interface';
import type {ValuesState, RegisterOptions, FieldSettingOptions} from '../hooks/types';

export function sortPathBySpec(spec: UnionSpecItem, prefix: string) {
    let sortPathArray: string[] = [];
    const path = prefix ? `${prefix}.${spec.name}` : spec.name;
    sortPathArray.push(path);
    if (spec.dataType === 'LIST') {
        (spec.items || []).forEach((child, index) => {
            sortPathArray = sortPathArray.concat(sortPathBySpec(child, `${path}.[${index}]`));
        });
    } else if (spec.dataType === 'OBJECT') {
        (spec.items || []).forEach((child) => {
            sortPathArray = sortPathArray.concat(sortPathBySpec(child, `${path}`));
        });
    } else if (spec.dataType === 'ALTERNATIVE') {
        (spec.enumValues || []).forEach((enumItem: EnumValuesSpecItem) => {
            const enumPath = `${path}.${enumItem.value}`;
            sortPathArray.push(enumPath);
            (enumItem.items || []).forEach((child) => {
                sortPathArray = sortPathArray.concat(sortPathBySpec(child, `${enumPath}`));
            });
        });
    }
    return sortPathArray;
}

export interface FormItem {
    path: string;
    spec: UnionSpecItem;
    parent: FormItem | null;
    getValue: (fieldName: string) => ValuesState;
    setValue: (values: ValuesState, ifTriggerFormChange?: boolean) => void;
}

export function createItem(
    path: string,
    getFieldValue: (fieldName: string) => ValuesState,
    setFieldValue: (fieldName: string, values: ValuesState, options?: FieldSettingOptions) => void,
    getFieldRegistry: (fieldName: string) => RegisterOptions
): FormItem {
    const spec = getFieldRegistry(path)?.spec;
    const parentPath = path.split('.').slice(0, -1).join('.');
    let parent = null;
    if (parentPath) {
        parent = createItem(parentPath, getFieldValue, setFieldValue, getFieldRegistry);
    }
    const fieldName = path;
    const getValue = (): ValuesState => {
        return getFieldValue(fieldName);
    };
    const setValue = (values: ValuesState, ifTriggerFormChange?: boolean): void => {
        // 注意：这个方法不会触发自动校验也不触发formchange，否则触发formchange 会导致死循环
        return setFieldValue(fieldName, values, {
            shouldValidate: false,
            ifUpdateCharsAboutList: true,
            ifTriggerFormChange: ifTriggerFormChange || false
        });
    };

    return {
        path,
        spec,
        parent,
        getValue,
        setValue
    };
}
